package main.smarthouse.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.CellEditEvent;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.map.OverlaySelectEvent;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.MapModel;
import org.primefaces.model.map.Marker;

import smarthouse.dto.ElectronicDTO;
import smarthouse.dto.HouseDTO;
import smarthouse.dto.PrivilegeDTO;
import smarthouse.dto.RoomDTO;
import smarthouse.dto.UserDTO;
import smarthouse.ejb.ElectronicDAORemote;
import smarthouse.ejb.HouseDAORemote;
import smarthouse.ejb.PrivilegeDAORemote;
import smarthouse.ejb.RoomDAORemote;

/**
 * @author Sergiu
 * 
 */
@SessionScoped
@ManagedBean(name = "houseBean")
public class HouseBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3361863989041306094L;

	@EJB
	private HouseDAORemote houseDAO;

	@EJB
	private RoomDAORemote roomDAO;

	@EJB
	private ElectronicDAORemote electronicDAO;

	@EJB
	private PrivilegeDAORemote privilegeDAO;

	private UserDTO loggedUser;

	private PrivilegeDTO loggedUserPrivilege;

	private int selectedRoom;

	private HouseDTO house;

	private HouseDTO newHouse = new HouseDTO();

	private MapModel simpleModel;

	private MapModel emptyModel;

	private MapModel newModel;

	private double lng;
	private double lat;
	private String title;
	private String input;

	private Marker marker;
	@SuppressWarnings("unused")
	private String mapCenter;

	private String housePass;
	private Boolean confirmEdit = false;

	private List<RoomDTO> rooms = new ArrayList<>();

	private List<ElectronicDTO> selectedRoomElectronics = new ArrayList<>();

	private String selectedRoomName;

	private PrivilegeDTO newPriv = new PrivilegeDTO();

	/**
	 * Bean Constructor
	 */
	public HouseBean() {

		emptyModel = new DefaultMapModel();
		simpleModel = new DefaultMapModel();
		newModel = new DefaultMapModel();
		house = (HouseDTO) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("selectedHouse");

		LatLng houseCoord = new LatLng(Double.parseDouble(house.getLatitude()),
				Double.parseDouble(house.getLongitude()));
		simpleModel.addOverlay(new Marker(houseCoord, house.getHouseName()));

	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public UserDTO getLoggedUser() {
		loggedUser = (UserDTO) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("loggedUser");
		return loggedUser;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setLoggedUser(UserDTO loggedUser) {
		this.loggedUser = loggedUser;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public PrivilegeDTO getLoggedUserPrivilege() {
		loggedUser = (UserDTO) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("loggedUser");
		loggedUserPrivilege = privilegeDAO.getPrivilegebyId(loggedUser
				.getUserId());
		return loggedUserPrivilege;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setLoggedUserPrivilege(PrivilegeDTO loggedUserPrivilege) {
		this.loggedUserPrivilege = loggedUserPrivilege;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public List<RoomDTO> getRooms() {

		if (house.getRooms() != null && rooms.isEmpty()) {
			for (int i : house.getRooms()) {

				rooms.add(roomDAO.getRoombyId(i));
			}
		}
		return rooms;

	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setRooms(List<RoomDTO> rooms) {
		this.rooms = rooms;
	}

	/**
	 * Verify house admin password
	 */
	public void checkHousePassword() {
		if (housePass.equals(house.getAdminPassword())) {
			confirmEdit = true;

		} else {
			confirmEdit = false;
		}
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public int getSelectedRoom() {
		return selectedRoom;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setSelectedRoom(int selectedRoom) {
		this.selectedRoom = selectedRoom;
		selectedRoomElectronics = new ArrayList<>();
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public List<ElectronicDTO> getSelectedRoomElectronics() {
		if (selectedRoom != 0 && selectedRoomElectronics.isEmpty())
			for (int i : roomDAO.getRoombyId(selectedRoom).getElectronics()) {
				selectedRoomElectronics.add(electronicDAO.getElectronicbyId(i));
			}
		return selectedRoomElectronics;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setSelectedRoomElectronics(
			List<ElectronicDTO> selectedRoomElectronics) {
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public MapModel getNewModel() {
		return newModel;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setNewModel(MapModel newModel) {
		this.newModel = newModel;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public PrivilegeDTO getNewPriv() {
		return newPriv;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public String getMapCenter() {
		return "" + house.getLatitude() + ", " + house.getLongitude() + "";
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setMapCenter(String mapCenter) {
		this.mapCenter = mapCenter;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setNewPriv(PrivilegeDTO newPriv) {
		this.newPriv = newPriv;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public Boolean getConfirmEdit() {
		return confirmEdit;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setConfirmEdit(Boolean confirmEdit) {
		this.confirmEdit = confirmEdit;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public String getHousePass() {
		return housePass;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setHousePass(String housePass) {
		this.housePass = housePass;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public String getInput() {
		return input;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setInput(String input) {
		this.input = input;
	}

	/**
	 * 
	 * @param message
	 */
	public void addMessage(FacesMessage message) {
		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public MapModel getEmptyModel() {
		emptyModel = new DefaultMapModel();
		return emptyModel;
	}

	/**
	 * 
	 * @param actionEvent
	 */
	public void addMarker(ActionEvent actionEvent) {
		Marker marker = new Marker(new LatLng(lat, lng), house.getHouseName());
		emptyModel.addOverlay(marker);

		addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Added",
				"Lat:" + lat + ", Lng:" + lng));
		house.setLatitude(String.valueOf(lat));
		house.setLongitude(String.valueOf(lng));
		saveHouseChanges();

	}

	/**
	 * Add user
	 */
	public void submit() {
		addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Form submitted", "Amount markers: "
						+ emptyModel.getMarkers().size() + ", Input: " + input));
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setEmptyModel(MapModel emptyModel) {
		this.emptyModel = emptyModel;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public double getLng() {
		return lng;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setLng(double lng) {
		this.lng = lng;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public double getLat() {
		return lat;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setLat(double lat) {
		this.lat = lat;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public HouseDTO getHouse() {
		return house;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setHouse(HouseDTO house) {
		this.house = house;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public MapModel getSimpleModel() {
		simpleModel = new DefaultMapModel();
		LatLng houseCoord = new LatLng(Double.parseDouble(house.getLatitude()),
				Double.parseDouble(house.getLongitude()));
		simpleModel.addOverlay(new Marker(houseCoord, house.getHouseName()));
		return simpleModel;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setSimpleModel(MapModel simpleModel) {
		this.simpleModel = simpleModel;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public String getSelectedRoomName() {
		return selectedRoomName;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setSelectedRoomName(String selectedRoomName) {
		this.selectedRoomName = selectedRoomName;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public HouseDTO getNewHouse() {
		return newHouse;
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public void setNewHouse(HouseDTO newHouse) {
		this.newHouse = newHouse;
	}

	/**
	 * 
	 * @param event
	 */
	public void onMarkerSelect(OverlaySelectEvent event) {
		marker = (Marker) event.getOverlay();

		addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Location selected", house.getHouseName()));
	}

	/**
	 * Getter/Setter
	 * 
	 * @return
	 */
	public Marker getMarker() {
		return marker;
	}

	/**
	 * 
	 * @param event
	 */
	public void handleFileUpload(FileUploadEvent event) {
		FacesMessage msg = new FacesMessage("Succesful", event.getFile()
				.getFileName() + " is uploaded.");
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	/**
	 * 
	 * @return
	 */
	public String createHouse() {
		FacesMessage msg = new FacesMessage("Added a new house");
		FacesContext.getCurrentInstance().addMessage(null, msg);

		return "userPage.xhtml?faces-redirect=true";

	}

	/**
 * 
 */
	public void saveHouseChanges() {

		if (houseDAO.updateHouse(house)) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("House information updated"));
			return;
		} else {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("House could not have been updated"));
			return;
		}
	}

	/**
	 * 
	 * @param e
	 */
	public void toggleSelectedRoom(ActionEvent e) {

		selectedRoom = (Integer) e.getComponent().getAttributes().get("roomId");
		selectedRoomElectronics = new ArrayList<>();
		selectedRoomName = roomDAO.getRoombyId(selectedRoom).getType();
	}

	/**
	 * 
	 * @param e
	 */
	public void updateRooms(CellEditEvent e) {
		int i = e.getRowIndex();
		RoomDTO r = rooms.get(i);

		roomDAO.updateRoom(r);

	}

	/**
	 * 
	 * @param e
	 */
	public void updateElectronics(CellEditEvent e) {
		int i = e.getRowIndex();
		ElectronicDTO r = selectedRoomElectronics.get(i);

		electronicDAO.updateElectronic(r);

	}

}
